package com.vip.jwt.common.utils.baidu;

import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.vip.jwt.common.exception.MyException;
import com.vip.jwt.common.utils.RedisUtil;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 百度人脸识别工具类
 */
public class BaiduFaceUtil {

    @Getter
    private static String API_KEY;

    @Getter
    private static String SECRET_KEY;

    @Value("${baidu-face-apikey}")
    public void setApiKey(String apiKey) {
        API_KEY = apiKey;
    }

    @Value("${baidu-face-secretkey}")
    public void setSecretKey(String secretKey) {
        SECRET_KEY = secretKey;
    }

    /**
     * 获取AccessToken
     * @return
     */
    private static String accessToken()
    {
        String url = "https://aip.baidubce.com/oauth/2.0/token";
        Map<String,Object> params = new HashMap<>(16);
        params.put("grant_type","client_credentials");
        params.put("client_id",API_KEY);
        params.put("client_secret",SECRET_KEY);
        return HttpRequest.get(url).form(params).execute().body();
    }

    /**
     * 将百度AccessToken存入Redis
     * @return
     */
    public static String getAccessToken(){
        String key = "baidu_face_access_token";
        // 首先验证Redis有没有accessToken
        Boolean bo = RedisUtil.hasKey(key);
        String accessTokenStr;
        if(bo){
            accessTokenStr = RedisUtil.get(key);
        }else{
            String jsonStr = accessToken();
            JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
            if(null!=jsonObject.get("error")){
                String error = jsonObject.get("error").toString();
                if("invalid_request".equals(error)){
                    throw new MyException(jsonObject.get("error_description").toString());
                }
            }
            accessTokenStr = jsonObject.get("access_token").toString();
            RedisUtil.set(key,accessTokenStr);
            int expires_in = Integer.parseInt(jsonObject.get("expires_in").toString());
            RedisUtil.expire(key,expires_in, TimeUnit.SECONDS);
        }
        return accessTokenStr;
    }

    /**
     * 人脸检测（是否是个人脸）
     * @param accessToken
     * @param imageBase64 图片的base64编码（注意：去掉头）
     * @return
     */
    public static String faceDetect(String accessToken,String imageBase64){
        String url = "https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=" + accessToken;
        Map<String,Object> params = new HashMap<>(16);
        params.put("image",imageBase64);
        // 图片类型 base64
        params.put("image_type","BASE64");
        // 最大人脸数
        params.put("max_face_num",1);
        // 人脸类型（真人、卡通）
        params.put("face_type","LIVE");
        // 活体检测
        params.put("liveness_control","HIGH");
        String jsonStr = new JSONObject(params).toString();
        return HttpRequest.post(url).body(jsonStr).execute().body();
    }

    /**
     * 人脸注册
     * @param groupId
     * @param userId
     * @param imageBase64 图片的base64编码（注意：去掉头）
     * @return
     */
    public static String faceUserAdd(String accessToken,String groupId,String userId,String imageBase64) {
        String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add?access_token=" + accessToken;
        Map<String,Object> params = new HashMap<>(16);
        params.put("image",imageBase64);
        // 组ID
        params.put("group_id",groupId);
        // 用户ID
        params.put("user_id",userId);
        String jsonStr = new JSONObject(params).toString();
        return HttpRequest.post(url).body(jsonStr).execute().body();
    }

    /**
     * 创建用户组
     * @param accessToken
     * @param groupId
     * @return
     */
    public static String groupAdd(String accessToken,String groupId)
    {
        String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/add?access_token=" + accessToken;
        Map<String,Object> params = new HashMap<>(16);
        // 组ID
        params.put("group_id",groupId);
        String jsonStr = new JSONObject(params).toString();
        return HttpRequest.post(url).body(jsonStr).execute().body();
    }

    /**
     * 组列表查询
     * @param page
     * @param limit
     * @return
     */
    public static String getGroupList(String accessToken,int page,int limit)
    {
        String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/getlist?access_token=" + accessToken;
        Map<String,Object> params = new HashMap<>(16);
        // 页数
        params.put("start",page);
        // 条数
        params.put("length",limit);
        String jsonStr = new JSONObject(params).toString();
        return HttpRequest.post(url).body(jsonStr).execute().body();
    }

    /**
     * 获取组中的用户列表
     * @param accessToken
     * @param groupId
     * @return
     */
    public static String getGroupUsers(String accessToken,String groupId)
    {
        String url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/group/getusers?access_token=" + accessToken;
        Map<String,Object> params = new HashMap<>(16);
        // 组ID
        params.put("group_id",groupId);
        String jsonStr = new JSONObject(params).toString();
        return HttpRequest.post(url).body(jsonStr).execute().body();
    }

    /**
     * 人脸搜索
     * @param groupId 组,字符串以逗号分割
     * @param imageBase64 图片的base64编码（注意：去掉头）
     * @return
     */
    public static String faceSearch(String accessToken,String groupId,String imageBase64)
    {
        String url = "https://aip.baidubce.com/rest/2.0/face/v3/search?access_token=" + accessToken;
        Map<String,Object> params = new HashMap<>(16);
        // 图片的base64编码
        params.put("image",imageBase64);
        // 图片类型 base64
        params.put("image_type","BASE64");
        // 组ID（如果是多个组，则字符串以逗号分割）
        params.put("group_id_list",groupId);
        String jsonStr = new JSONObject(params).toString();
        return HttpRequest.post(url).body(jsonStr).execute().body();
    }

    /**
     * 人脸对比
     * @param accessToken
     * @param imageBase64_1 第一张图片的base64编码（注意：去掉头）
     * @param imageBase64_2 第二张图片的base64编码（注意：去掉头）
     * @return
     */
    public static String faceMatch(String accessToken,String imageBase64_1,String imageBase64_2)
    {
        String url = "https://aip.baidubce.com/rest/2.0/face/v3/match?access_token=" + accessToken;
        Map<String,Object> face1 = new HashMap<>(16);
        // 图片的base64编码
        face1.put("image",imageBase64_1);
        // 图片类型 base64
        face1.put("image_type","BASE64");
        Map<String,Object> face2 = new HashMap<>(16);
        // 图片的base64编码
        face2.put("image",imageBase64_2);
        // 图片类型 base64
        face2.put("image_type","BASE64");
        JSONObject jsonObject_1 = JSONUtil.parseObj(face1);
        JSONObject jsonObject_2 = JSONUtil.parseObj(face2);
        JSONArray jsonArray = new JSONArray();
        jsonArray.add(jsonObject_1);
        jsonArray.add(jsonObject_2);
        String jsonArrStr = new JSONArray(jsonArray).toString();
        return HttpRequest.post(url).body(jsonArrStr).execute().body();
    }

    /**
     * 身份认证（在百度云控制台人脸识别模块中的人脸实名认证中创建H5实名认证，然后关联应用才可使用此接口）
     * @param accessToken
     * @param idCard 身份证号
     * @param name 姓名
     * @return
     */
    public static String isIdentical(String accessToken,String idCard,String name){
        String url = "https://aip.baidubce.com/rest/2.0/face/v3/person/idmatch?access_token=" + accessToken;
        Map<String,Object> params = new HashMap<>(16);
        // 姓名
        params.put("name", name);
        // 身份证号
        params.put("id_card_number", idCard);
        String jsonStr = new JSONObject(params).toString();
        return HttpRequest.post(url).body(jsonStr).execute().body();
    }

    /**
     * 实名认证（带照片）（在百度云控制台人脸识别模块中的人脸实名认证中创建H5实名认证，然后关联应用才可使用此接口）
     * @param accessToken
     * @param imageBase64 图片的base64编码（注意：去掉头）
     * @param idCard 身份证号
     * @param name 姓名
     * @return
     */
    public static String isIdentical(String accessToken,String imageBase64,String idCard,String name){
        String url = "https://aip.baidubce.com/rest/2.0/face/v3/person/verify?access_token=" + accessToken;
        Map<String,Object> params = new HashMap<>(16);
        // 图片的base64编码
        params.put("image",imageBase64);
        // 姓名
        params.put("name", name);
        // 身份证号
        params.put("id_card_number", idCard);
        // 图片类型 base64
        params.put("image_type","BASE64");
        // 图片质量控制
        params.put("quality_control", "NONE");
        // 活体检测控制
        params.put("liveness_control", "NONE");
        String jsonStr = new JSONObject(params).toString();
        return HttpRequest.post(url).body(jsonStr).execute().body();
    }

}
